/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package creature;

import java.awt.Color;
import java.awt.Point;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import world.World;

/**
 *
 * @author leadiv
 *  By Default a creature is a small green 1 pixel dot that runs east to west.
 */
public class GameOfLife extends Creature {
    private Point[] move;

    public GameOfLife(int x, int y, int id) {
        super(x,y,id);

        this.move = new Point[8];
        move[0] = new Point(-1,1);
        move[1] = new Point(0,1);
        move[2] = new Point(1,1);
        move[3] = new Point(-1,0);
        move[4] = new Point(1,0);
        move[5] = new Point(-1,-1);
        move[6] = new Point(0,-1);
        move[7] = new Point(1,-1);
    }
    
    @Override
    public void move(World w) 
    {
        // 0,8 death
        // 1-3 lonely
        // 4   birth
        // 5-7 crowded
       Color[] neighbors = new Color[8];
       int cnt=0, avg1, avg2, avg3, sum, mov, i;
       Vector<Integer> high = new Vector<Integer>(),
                       mid = new Vector<Integer>(),
                       low = new Vector<Integer>();    // this is for density index values.

       neighbors[0] = w.getpix(this.getX()-1, this.getY()+1);
       neighbors[1] = w.getpix(this.getX()  , this.getY()+1);
       neighbors[2] = w.getpix(this.getX()+1, this.getY()+1);
       neighbors[3] = w.getpix(this.getX()-1, this.getY());
       neighbors[4] = w.getpix(this.getX()+1, this.getY());
       neighbors[5] = w.getpix(this.getX()-1, this.getY()-1);
       neighbors[6] = w.getpix(this.getX()  , this.getY()-1);
       neighbors[7] = w.getpix(this.getX()+1, this.getY()-1);



       for(i=0; i<8; i++) {
           avg1 = neighbors[(i-1<0)?7:i].equals(Color.BLACK) ? 0 : 1;
           avg2 = neighbors[i].equals(Color.BLACK) ? 0 : 1;
           avg3 = neighbors[(i+1)%8].equals(Color.BLACK) ? 0 : 1;
           if(0 == avg2) {  // this spot is empty
               sum = avg1+avg2+avg3;
               if(sum == 2) high.add(i);
               if(sum == 1) mid.add(i);
               if(sum == 0) low.add(i);
           } else {
               cnt++;
           }
       }

       if(cnt == 8 || cnt == 0) { // die :(
           this.setSkinColor(Color.BLACK);
           w.death(this.getX(), this.getY(), this.getId(), this);
           return;
       }

       if(cnt <= 3) { // lonely -- seek greatest density
           if(!high.isEmpty()) {
               mov = high.get(Double.valueOf(Math.random() * high.size()).intValue());
           } else if(!mid.isEmpty()) {
               mov = mid.get(Double.valueOf(Math.random() * mid.size()).intValue());
           } else {
               mov = low.get(Double.valueOf(Math.random() * low.size()).intValue());
           }

           w.place(this.getX() + move[mov].x, this.getY() + move[mov].y, this.getId());
           this.setSkinColor(Color.GREEN);
           return;
       }

       if(cnt == 4) { // birth -- don't move
           high.addAll(mid);
           high.addAll(low);
           mov = high.get(Double.valueOf(Math.random() * high.size()).intValue());

           w.birth(this.getX() + move[mov].x, this.getY() + move[mov].y);
           this.setSkinColor(Color.YELLOW);
           return;
       }


       // this is crowded option!
       if(!low.isEmpty()) {
           mov = low.get(Double.valueOf(Math.random() * low.size()).intValue());
       } else if(!mid.isEmpty()) {
           mov = mid.get(Double.valueOf(Math.random() * mid.size()).intValue());
       } else {
           mov = high.get(Double.valueOf(Math.random() * high.size()).intValue());
       }

       w.place(this.getX() + move[mov].x, this.getY() + move[mov].y, this.getId());
       this.setSkinColor(Color.RED);


    }
}
